<?php
// Copyright (c) 2013 Karpov Sergey

// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sub-license, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:

// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.

// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
// IN THE SOFTWARE.


// Authors:  Karpov Sergey <karpoff.s@gmail.com>

/**
 * Class to generating xmltv format file
 *
 * @package Library_XMLTV
 * @category DOM
 * @version 0.0.5
 * @author Karpov Sergey <karpoff.s@gmail.com>
 * @license MIT License
 */

class XMLTV
{
	private $xml;
	// xml tag`s
	private $tv;
	private $channel;
	private $programme;
	private $credits;
	private $video;
	private $rating;

		// the primary initialization
		function __construct ($version='1.0', $codepage='utf-8', $source_data_url='',$generator_info_name='',$generator_info_url='' )
		{
			$this->xml = new DOMDocument($version, $codepage);
			$this->tv = $this->xml->createElement( 'tv', '');
			$this->tv->setAttribute( 'source-info-url', 'http://karpoff.zz.mu/libxmltv' );
			$this->tv->setAttribute( 'source-info-name', 'XMLTV library writing Karpov Sergey' );
			$this->tv->setAttribute( 'source-data-url', $source_data_url );
			$this->tv->setAttribute( 'generator-info-name', $generator_info_name );
			$this->tv->setAttribute( 'generator-info-url', $generator_info_url );
		}
		/* Staring Channel tag`s! */
		// tag channel->tv
        public function CreateChannel ( $id )
        {
            $element = $this->xml->createElement( 'channel', NULL );
            $element->setAttribute( 'id', $id );
            $this->channel[$id] = $element;
        }
			// tag display-name->channel
			public function DisplayName ( $displayname,$lang,$id )
			{
				$element = $this->xml->createElement( 'display-name', $displayname );
				$element->setAttribute( 'lang', $lang );
				$this->channel[$id]->appendChild( $element  );
			}
			// tag icon->channel
			public function Icon ( $url,$id )
			{
				$element = $this->xml->createElement( 'icon' );
				$element->setAttribute( 'src', $url );
				$this->channel[$id]->appendChild( $element  );
			}
		/* Endings Channel tag`s! */

		/* Starting programme tag`s! */
		// tag programme->tv - Examples: '200007281733 BST', '200209', '19880523083000 +0300'.  (BST == +0100.)
        public function Programme ( $start='',$stop='',$id='',$count )
        {
	      $element = $this->xml->createElement( 'programme', NULL );
	      $element->setAttribute( 'start', $start );
	      $element->setAttribute( 'stop', $stop );
	      $element->setAttribute( 'channel', $id );
	      $this->programme[$count]= $element;
        }
			// tag title->programme
			public function Title ( $title='',$lang='en',$count )
			{
				$element = $this->xml->createElement( 'title', $title );
				$element->setAttribute( 'lang', $lang );
				$this->programme[$count]->appendChild( $element  );
			}

			// tag desc->programme
			public function Desc ( $desc='',$lang='en',$count )
			{
				$element = $this->xml->createElement( 'desc', $desc );
				$element->setAttribute( 'lang', $lang );
				$this->programme[$count]->appendChild( $element  );
			}

			// tag category->programme
			public function Category ( $category='',$lang='en',$count )
			{
				$element = $this->xml->createElement( 'category', $category );
				$element->setAttribute( 'lang', $lang );
				$this->programme[$count]->appendChild( $element  );
			}

			/* Credits start */
			// tag credits->programme
			public function createCredits ( $count )
			{
				$element = $this->xml->createElement( 'credits', NULL );
				$this->credits[$count] = $element;
			}
				// tag director->credits->programme
				public function Director ( $director='',$count )
				{
					$element = $this->xml->createElement( 'director', $director );
					$this->credits[$count]->appendChild( $element );
				}
				// tag actor->credits->programme
				public function Actor ( $actor='',$count )
				{
					$element = $this->xml->createElement( 'actor', $actor );
					$this->credits[$count]->appendChild( $element );
				}
				// tag writer->credits->programme
				public function Writer ( $writer='',$count )
				{
					$element = $this->xml->createElement( 'writer', $writer );
					$this->credits[$count]->appendChild( $element );
				}
				// tag adapter->credits->programme
				public function Adapter ( $adapter='',$count )
				{
					$element = $this->xml->createElement( 'adapter', $adapter );
					$this->credits[$count]->appendChild( $element );
				}
				// tag producer->credits->programme
				public function Producer ( $producer='',$count )
				{
					$element = $this->xml->createElement( 'producer', $producer );
					$this->credits[$count]->appendChild( $element );
				}
				// tag composer->credits->programme
				public function Composer ( $composer='',$count )
				{
					$element = $this->xml->createElement( 'composer', $composer );
					$this->credits[$count]->appendChild( $element );
				}
				// tag editor->credits->programme
				public function Editor ( $editor='',$count )
				{
					$element = $this->xml->createElement( 'editor', $editor );
					$this->credits[$count]->appendChild( $element );
				}
				// tag presenter->credits->programme
				public function Presenter ( $presenter='',$count )
				{
					$element = $this->xml->createElement( 'presenter', $presenter );
					$this->credits[$count]->appendChild( $element );
				}
				// tag commentator->credits->programme
				public function Commentator ( $commentator='',$count )
				{
					$element = $this->xml->createElement( 'commentator', $commentator );
					$this->credits[$count]->appendChild( $element );
				}
				// tag guest->credits->programme
				public function Guest ( $guest='',$count )
				{
					$element = $this->xml->createElement( 'guest', $guest );
					$this->credits[$count]->appendChild( $element );
				}
			/* Credits ends! */
			// tag country->programme
			public function Country ( $country='',$count )
			{
				$element = $this->xml->createElement( 'country', $country );
				$this->programme[$count]->appendChild( $element  );
			}

			// tag date->programme
			public function Date ( $date='',$count )
			{
				$element = $this->xml->createElement( 'date', $date );
				$this->programme[$count]->appendChild( $element  );
			}
			
			/* Start episode-num  */
			// tag episode-num->programme
			public function Episode ( $episode='', $system='', $count )
			{
				$element = $this->xml->createElement( 'episode-num', $episode );
				$element->setAttribute( 'system', $system );
				$this->programme[$count]->appendChild( $element  );
			}
			/* episode-num ends! */
 
			/* Start Video */
			// tag video->programme
			public function createVideo ( $count )
			{
				$element = $this->xml->createElement( 'video', NULL );
				$this->video[$count] = $element;
			}
				// tag aspect->video - The horizontal:vertical aspect ratio, eg '4:3' or '16:9'.
				public function Aspect ( $aspect='', $count )
				{
					$element = $this->xml->createElement( 'aspect', $aspect );
					$this->video[$count]->appendChild( $element );
				}
				// tag colour->video - 'yes' for colour, 'no' for black-and-white.
				public function Colour ( $colour='yes', $count )
				{
					$element = $this->xml->createElement( 'colour', $colour );
					$this->video[$count]->appendChild( $element );
				}
				// tag quality->video - information on the quality, eg 'HDTV', '800x600'.
				public function Quality ( $quality='', $count )
				{
					$element = $this->xml->createElement( 'quality', $quality );
					$this->video[$count]->appendChild( $element );
				}
			/* Video ends! */
 
			/* Start Rating */
			// tag rating->programme
			public function createRating ( $system='', $count )
			{
				$element = $this->xml->createElement( 'rating', NULL );
				$element->setAttribute( 'system', $system );
				$this->rating[$count] = $element;
			}
				// tag value->rating
				public function RatingValue ( $value='', $count )
				{
					$element = $this->xml->createElement( 'value', $value );
					$this->rating[$count]->appendChild( $element );
				}
				// tag icon->rating
				public function RatingIcon ( $src='', $count )
				{
					$element = $this->xml->createElement( 'icon' );
					$element->setAttribute( 'src', $src );
					$this->rating[$count]->appendChild( $element );
				}
			/* Rating ends! */
			
			/* Start StarRating */
			// tag star-rating->programme
			private function createStarRating($subtag='',$count)
			{
				$element = $this->xml->createElement( 'star-rating', '' );
				$element->appendChild( $subtag );
				$this->programme[$count]->appendChild( $element  );
			}
				// tag value->star-rating
				public function StarRating ( $value='',$count )
				{
					$element = $this->xml->createElement( 'value', $value );
					$this->createStarRating( $element,$count );
				}
			/* StarRating ends! */
		/* Ending programme tag`s! */

	// public function compile all tag`s to the main tv tag
	public function Compile ( $tag )
    {
		switch($tag) {
			case 'channel':
				// add channel tag to the main tv tag
				foreach ( $this->channel as $count => $element  ) {
					  $this->tv->appendChild( $this->channel[$count] );
 				}
			break;
			case 'programme':
 				foreach ( $this->programme as $count => $element ) {
					// add credits tag if need to the programme tag
					if (!empty($this->credits[$count]))
					{
						$this->programme[$count]->appendChild( $this->credits[$count] );
						unset($this->credits[$count]);
					}
					
					// add video tag if need to the programme tag
					if (!empty($this->video[$count]))
					{
						$this->programme[$count]->appendChild( $this->video[$count] );
						unset($this->video[$count]);
					}
					
					// add rating tag if need to the programme tag
					if (!empty($this->rating[$count]))
					{
						$this->programme[$count]->appendChild( $this->rating[$count] );
						unset($this->rating[$count]);
					}
					
					// add programme to the main tag tv
					$this->tv->appendChild( $this->programme[$count] );
					unset($this->programme[$count]);
				}
			break;
			
		}
		unset($tag);
	}
	
	// public function for output structured xml
	public function OutXMLTV()
	{
		$this->xml->appendChild( $this->tv );
		$outXML = $this->xml->saveXML();
		$tmpxml = new DOMDocument();
		$tmpxml->preserveWhiteSpace = false;
		$tmpxml->formatOutput = true;
		$tmpxml->loadXML($outXML);
		$outXML = $tmpxml->saveXML();
		return $outXML;
	}
}

?>